package com.dh.volatileTest;

/**
 * 
 * 　当对非 volatile 变量进行读写的时候，每个线程先从内存拷贝变量到CPU缓存中。如果计算机有多个CPU，每个线程可能在不同的CPU上被处理，这意味着每个线程可以拷贝到不同的 CPU cache 中。

　　而声明变量是 volatile 的，JVM 保证了每次读变量都从内存中读，跳过 CPU cache 这一步。

       当一个变量定义为 volatile 之后，将具备两种特性：
　　1.保证此变量对所有的线程的可见性，这里的“可见性”，如本文开头所述，当一个线程修改了这个变量的值，
    volatile 保证了新值能立即同步到主内存，以及每次使用前立即从主内存刷新。但普通变量做不到这点，
         普通变量的值在线程间传递均需要通过主内存（详见：Java内存模型）来完成。

　　2.禁止指令重排序优化。有volatile修饰的变量，赋值后多执行了一个“load addl $0x0, (%esp)”操作，
      这个操作相当于一个内存屏障（指令重排序时不能把后面的指令重排序到内存屏障之前的位置），
      只有一个CPU访问内存时，并不需要内存屏障；（什么是指令重排序：是指CPU采用了允许将多条指令不按
      程序规定的顺序分开发送给各相应电路单元处理）。
 * @author liguobao
 *
 */
public class NoVisibility {
	
	private static /**volatile**/ boolean ready;
    private static /**volatile**/ int number;
    private static class ReaderThread extends Thread {
        @Override
        public void run() {
            while(!ready) {
                try {
					//Thread.sleep(1000);
                	Thread.yield();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
            }
            System.out.println(number);
        }
    }
    public static void main(String[] args) {
        new ReaderThread().start();
        try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        number = 42;
        ready = true;
    }

}
